﻿using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace FlashUnityPlayer
{
  internal class FlashUnityMessageFilter : IMessageFilter
  {

    private const int WM_MOUSEMOVE = 0x0200;
    private const int WM_MOUSEWHEEL = 0x020A;
    private const int WM_LBUTTONDOWN = 0x0201;
    private const int WM_LBUTTONUP = 0x0202;
    private const int WM_LBUTTONDBLCLK = 0x0203;
    private const int WM_RBUTTONDOWN = 0x0204;
    private const int WM_RBUTTONUP = 0x0205;
    private const int WM_MOUSEHOVER = 0x2A1;
    private const int WM_MOUSELEAVE = 0x2a3;

    private const int WM_IME_SELECT = 0x285;
    private const int WM_KEYDOWN = 0x100;
    private const int WM_KEYUP = 0x101;
    private const int APPCOMMAND_VOLUME_MUTE = 0x80000;
    private const int APPCOMMAND_VOLUME_UP = 0xA0000;
    private const int APPCOMMAND_VOLUME_DOWN = 0x90000;
    private const int WM_APPCOMMAND = 0x319;
    private const int WM_ACTIVATEAPP = 0x1C;
    private const int WM_SHOWWINDOW = 0x18;

    public event MouseEventHandler DoubleClick;
    public event MouseEventHandler LeftMouseDown;
    public event MouseEventHandler LeftMouseUp;
    public event MouseEventHandler RightMouseDown;
    public event MouseEventHandler RightMouseUp;
    public event MouseEventHandler MouseMove;
    public event MouseEventHandler MouseHover;
    public event MouseEventHandler MouseLeave;

    [DllImport("user32.dll")]
    public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg,
        IntPtr wParam, IntPtr lParam);

    public bool PreFilterMessage(ref Message m)
    {
      
      {
        if (m.Msg == WM_LBUTTONDOWN)
        {
          if (this.LeftMouseDown != null) this.LeftMouseDown(this, new MouseEventArgs(MouseButtons.Left, 1, Cursor.Position.X, Cursor.Position.Y, 0)); return false;
        }
        else if (m.Msg == WM_LBUTTONUP)
        {
          if (this.LeftMouseUp != null) this.LeftMouseUp(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0)); return false;
        }
        else if (m.Msg == WM_MOUSEMOVE)
        {
          if (this.MouseMove != null) this.MouseMove(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0)); return false;
        }
        else if (m.Msg == WM_RBUTTONDOWN)
        {
          if (this.RightMouseDown != null) this.RightMouseDown(this, new MouseEventArgs(MouseButtons.Left, 1, Cursor.Position.X, Cursor.Position.Y, 0)); return true;
        }
        else if (m.Msg == WM_RBUTTONUP)
        {
          if (this.RightMouseUp != null) this.RightMouseUp(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0)); return true;
        }
        else if (m.Msg == WM_LBUTTONDBLCLK)
        {
          if (this.DoubleClick != null) this.DoubleClick(this, new MouseEventArgs(MouseButtons.Left, 2, Cursor.Position.X, Cursor.Position.Y, 0)); return false;
        }
        else if (m.Msg == WM_MOUSEHOVER)
        {
          if (this.MouseHover != null) this.MouseHover(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0)); return false;
        }
        else if (m.Msg == WM_MOUSELEAVE)
        {
          if (this.MouseLeave != null) this.MouseLeave(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0)); return false;
        }
        else if (m.Msg == WM_KEYDOWN)
        {
          Keys key = (Keys)(int)m.WParam & Keys.KeyCode;
          if (key == Keys.Oemplus)
          {
            SendMessageW(m.HWnd, WM_APPCOMMAND, m.HWnd,
                  (IntPtr)APPCOMMAND_VOLUME_UP);
            return true;
          }
          else if (key == Keys.OemMinus)
          {
            SendMessageW(m.HWnd, WM_APPCOMMAND, m.HWnd,
                  (IntPtr)APPCOMMAND_VOLUME_DOWN);
            return true;
          }     
        }
        return false;
      }
    }
  }
}
